//
//  ViewController.m
//  20-XML-SAXAndDOM
//
//  Created by mafeng on 16/8/10.
//  Copyright © 2016年 mafeng. All rights reserved.
//

#import "ViewController.h"
#import "Student.h"
#import "XMLReader.h"
#import "GDataXMLNode.h"
@interface ViewController ()<NSXMLParserDelegate>
@property (nonatomic, strong) NSMutableArray *stuArray;
@property (nonatomic, strong) NSMutableArray *domStuArray;
@property (nonatomic, copy) NSString *currentElementName;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@"xml"];
    NSError *error = nil;
    NSData *xmlData = [NSData dataWithContentsOfFile:path];
    // 将xml结构, 转化为
    NSDictionary *xmlDic = [XMLReader  dictionaryForXMLData:xmlData error:&error];
    NSLog(@"%@", xmlDic);
    // Do any additional setup after loading the view, typically from a nib.
}
//*************************XML解析***********************//
// XML 分为两种解析方式,
// 第一种: SAX 逐行解析 --- 使用系统的解析器 NSXMLParser
//
- (IBAction)saxParse:(id)sender {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@"xml"];
    NSData *xmlData = [NSData dataWithContentsOfFile:path];
    // 初始化解析器
    NSXMLParser *xmlParse = [[NSXMLParser alloc] initWithData:xmlData];
    // 签代理
    xmlParse.delegate = self;
    // 运行解析器
    [xmlParse parse];
}

// 解析器开始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    self.stuArray = [NSMutableArray array];
}
// 逐行解析时, 遇到结点头 调用的方法(方法的回调),
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
    NSLog(@"节点头: %@", elementName);
    _currentElementName = elementName; //记录当前节点, 方便赋值
    if ([elementName isEqualToString:@"student"]) {
        Student *stu = [Student new];
        [_stuArray addObject:stu];
    }
}
// 节点的值, 根据节点决定值. 没有值对应的结果 \n\t \n\t\t
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    // 如果不判断@" "和tab , 采用没有注释的代码!!
    //if (![string hasSuffix:@" "] && ![string hasSuffix:@"\n"]) {
    if (_currentElementName) {
        NSLog(@"节点值: %@ --- 结束", string);
        // 取到最后一个stu
        Student *stu = [_stuArray lastObject];
        // kvc 赋值
        [stu setValue:string forKey:_currentElementName];
    }
   // }
    
    // String 是 \n\t (一个回车, 一(或多)个制表符(根据实际xml文件判断))
   // NSLog(@"节点值: %@ --- 结束", string);
}

// 遇到节点尾 方法的回调, 判断当前节点的结束
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSLog(@"节点尾: /%@", elementName);
    _currentElementName = nil; // 再节点尾置为空
}

// 解析器结束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"%@", _stuArray);
}
// 解析失败的协议方法
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(@"解析失败时, 调用%@", parseError);
}

//*************************DOM解析*************************//
// 关于GDataXMLNode的引入
// 1. 引入.h与.m文件
// 2. 引入系统动态库libxml2.tbd(快捷方式)
// 3. 根据GDateXMLNode头文件提示, 添加/usr/include/libxml2
// 4. 如果是ARC环境, 需对文件进行MRC编译, 添加-fno-objc-arc
- (IBAction)domParse:(id)sender {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@"xml"];
    NSError *error = nil;
    NSData *xmlData = [NSData dataWithContentsOfFile:path];
    // 1. 创建 GDataXMLDocument 对象
    // 根据 XML 的Data数据生成一个🌲树形的机构的 Document
    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
    // 2. 根据 Document 获取根节点
    GDataXMLElement *rootElement = [document rootElement];
    NSLog(@"❤️:%@", rootElement);
    // 3. 根据根节点获取 子节点的数组
    NSArray *rootChildElement = rootElement.children;
    // 初始化数组 
    self.domStuArray = [NSMutableArray array];
    // 4. 遍历子节点数组
    for (GDataXMLElement *childElement in rootChildElement) {
        NSLog(@"childElement name: %@", childElement.name);
        // 5. 对应所有的student的节点
        Student *stu = [Student new];
        [self.domStuArray addObject:stu];
        // 6. 遍历student节点的所有子节点
        for (GDataXMLElement *grandSonElement in childElement.children) {
            NSLog(@"grandSonElement name:%@", grandSonElement.stringValue);
            // 7. 赋值
            [stu setValue:grandSonElement.stringValue forKey:grandSonElement.name];
        }
    }
    NSLog(@"%@", self.domStuArray);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
